package dynamic;

import apply.data.Person;
import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * 反射的动态性
 */
public class DynamicTest {
    // 静态性
    public Person getInstance() {
        return new Person();
    }

    // 反射的动态性
    public <T> T getInstance(String className) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class<?> aClass = Class.forName(className);
        Constructor<?> declaredConstructor = aClass.getDeclaredConstructor();
        declaredConstructor.setAccessible(true);
        return (T) declaredConstructor.newInstance();
    }

    @Test
    public void test1() throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        Person p1 = getInstance();
        p1.age = 11;
        System.out.println(p1);

        String className = "apply.data.Person";
        Person person = getInstance(className);
        System.out.println(person);

        String className2 = "java.util.Date";
        Date instance = getInstance(className2);
        System.out.println(instance);

    }

    public Object invoke(String classname, String methodName) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class<?> clazz = Class.forName(classname);
        Constructor<?> constructor = clazz.getDeclaredConstructor();
        constructor.setAccessible(true);
        Object object = constructor.newInstance();
        Method declaredMethod = clazz.getDeclaredMethod(methodName);
        declaredMethod.setAccessible(true);
        return declaredMethod.invoke(object);

    }

    @Test
    public void test2() throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        String classname = "apply.data.Person";
        String methodName="show";
        System.out.println(invoke(classname, methodName));
    }
}
